home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d20
/
bsrc_250.arc
/
ZSEND.C
< prev
Wrap
Text File
|
1991-09-16
|
35KB
|
997 lines
/*--------------------------------------------------------------------------*/
/* */
/* */
/* ------------ Bit-Bucket Software, Co. */
/* \ 10001101 / Writers and Distributors of */
/* \ 011110 / Freely Available<tm> Software. */
/* \ 1011 / */
/* ------ */
/* */
/* (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
/* */
/* */
/* Zmodem file transmission module */
/* */
/* */
/* For complete details of the licensing restrictions, please refer */
/* to the License agreement, which is published in its entirety in */
/* the MAKEFILE and BT.C, and also contained in the file LICENSE.250. */
/* */
/* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
/* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
/* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
/* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */
/* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */
/* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */
/* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */
/* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */
/* */
/* */
/* You can contact Bit Bucket Software Co. at any one of the following */
/* addresses: */
/* */
/* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */
/* P.O. Box 460398 AlterNet 7:491/0 */
/* Aurora, CO 80046 BBS-Net 86:2030/1 */
/* Internet f491.n343.z1.fidonet.org */
/* */
/* Please feel free to contact us at any time to share your comments about */
/* our software and/or licensing policies. */
/* */
/* */
/* This module is based largely on a similar module in OPUS-CBCS V1.03b. */
/* The original work is (C) Copyright 1986, Wynn Wagner III. The original */
/* authors have graciously allowed us to use their code in this work. */
/* */
/*--------------------------------------------------------------------------*/
/* Include this file before any other includes or defines! */
#include "includes.h"
/*--------------------------------------------------------------------------*/
/* Private routines */
/*--------------------------------------------------------------------------*/
void ZS_SendBinaryHeader (unsigned short, byte *);
void ZS_32SendBinaryHeader (unsigned short, byte *);
void ZS_SendData (byte *, int, unsigned short);
void ZS_32SendData (byte *, int, unsigned short);
void ZS_SendByte (byte);
int ZS_GetReceiverInfo (void);
int ZS_SendFile (int, int);
int ZS_SendFileData (int);
int ZS_SyncWithReceiver (int);
void ZS_EndSend (void);
/*--------------------------------------------------------------------------*/
/* Private data */
/*--------------------------------------------------------------------------*/
static FILE *Infile; /* Handle of file being sent */
static long Strtpos; /* Starting byte position of */
/* download */
static long LastZRpos; /* Last error location */
static long ZRPosCount; /* ZRPOS repeat count */
static long Txpos; /* Transmitted file position */
static int Rxbuflen; /* Receiver's max buffer */
/* length */
static int Rxflags; /* Receiver's flags */
/*--------------------------------------------------------------------------*/
/* SEND ZMODEM (send a file) */
/* returns TRUE (1) for good xfer, FALSE (0) for bad */
/* sends one file per call; 'fsent' flags start and end of batch */
/*--------------------------------------------------------------------------*/
int Send_Zmodem (char *fname, char *alias, int fsent, int wazoo)
{
register byte *p;
register byte *q;
struct stat f;
int i;
int rc = TRUE;
char j[100];
#ifdef DEBUG
show_debug_name ("send_Zmodem");
#endif
IN_XON_ENABLE ();
z_size = 0;
Infile = NULL;
if (fname && !(fullscreen && un_attended))
set_xy ("");
switch (fsent)
{
case 0:
Z_PutString ((byte *)"rz\r");
Z_PutLongIntoHeader (0L);
Z_SendHexHeader (ZRQINIT, (byte *)Txhdr);
/* Fall through */
case NOTHING_TO_DO:
Rxtimeout = 200;
if (ZS_GetReceiverInfo () == ERROR)
{
XON_DISABLE ();
XON_ENABLE ();
return FALSE;
}
}
Rxtimeout = (int) (614400L / (long) cur_baud.rate_value);
if (Rxtimeout < 100)
Rxtimeout = 100;
if (fname == NULL)
goto Done;
/*--------------------------------------------------------------------*/
/* Prepare the file for transmission. Just ignore file open errors */
/* because there may be other files that can be sent. */
/*--------------------------------------------------------------------*/
Filename = fname;
CLEAR_IOERR ();
if ((Infile = share_fopen (Filename, read_binary, DENY_WRITE)) == NULL)
{
(void) got_error (MSG_TXT(M_OPEN_MSG), Filename);
rc = OK;
goto Done;
}
if (isatty (fileno (Infile)))
{
errno = 1;
(void) got_error (MSG_TXT(M_DEVICE_MSG), Filename);
rc = OK;
goto Done;
}
/*--------------------------------------------------------------------*/
/* Send the file */
/* Display outbound filename, size, and ETA for sysop */
/*--------------------------------------------------------------------*/
(void) stat (Filename, &f);
i = (int) (f.st_size * 10 / cur_baud.rate_value + 53) / 54;
(void) sprintf (j, "Z-Send %s, %ldb, %d min.", Filename, f.st_size, i);
file_length = f.st_size;
if (un_attended && fullscreen)
{
clear_filetransfer ();
sb_move ( file_hWnd, 1, 2);
FlLnModeSet( FILE_LN_2, 1 );
sb_puts( GetDlgItem( file_hWnd, FILE_LN_1 ), j );
elapse_time ();
(void) sprintf (j, "%3d min", i);
sb_move ( file_hWnd, 2, 69);
FlLnModeSet( FILE_LN_2, 1 );
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_DTTM ), j );
sb_show ();
}
else
{
(void) printf ("%s", j);
set_xy (NULL);
locate_x += 2;
}
/*--------------------------------------------------------------------*/
/* Get outgoing file name; no directory path, lower case */
/*--------------------------------------------------------------------*/
#ifndef NEW_PATH_STUFF
for (p = (byte *)((alias != NULL) ? alias : Filename), q = Txbuf; *p;)
{
if ((*p == '/') || (*p == '\\') || (*p == ':'))
q = Txbuf;
else *q++ = (char) tolower (*p);
p++;
}
*q++ = '\0';
p = q;
#else
p = ZMdmFlNmCndtn( Txbuf,
((alias != NULL) ? alias : Filename),
NULL,
0 );
p += strlen( p );
q = ++p;
#endif
/*--------------------------------------------------------------------*/
/* Zero out remainder of file header packet */
/*--------------------------------------------------------------------*/
while (q < (Txbuf + KSIZE))
*q++ = '\0';
/*--------------------------------------------------------------------*/
/* Store filesize, time last modified, and file mode in header packet */
/*--------------------------------------------------------------------*/
(void) sprintf ((char *)p, "%lu %lo %o", f.st_size, f.st_mtime, f.st_mode);
/*--------------------------------------------------------------------*/
/* Transmit the filename block and { the download */
/*--------------------------------------------------------------------*/
throughput (0, 0L);
/*--------------------------------------------------------------------*/
/* Check the results */
/*--------------------------------------------------------------------*/
switch (ZS_SendFile (1 + strlen ((char *)p) + (int) (p - Txbuf), wazoo))
{
case ERROR:
/*--------------------------------------------------*/
/* Something tragic happened */
/*--------------------------------------------------*/
goto Err_Out;
case OK:
/*--------------------------------------------------*/
/* File was sent */
/*--------------------------------------------------*/
CLEAR_IOERR ();
(void) fclose (Infile);
Infile = NULL;
status_line ("%s-Z%s %s", MSG_TXT(M_FILE_SENT), Crc32t ? "/32" : "", Filename);
update_files (1);
goto Done;
case ZSKIP:
status_line (MSG_TXT(M_REMOTE_REFUSED), Filename);
rc = SPEC_COND; /* Success but don't
* truncate! */
goto Done;
default:
/*--------------------------------------------------*/
/* Ignore the problem, get next file, trust other */
/* error handling mechanisms to deal with problems */
/*--------------------------------------------------*/
goto Done;
} /* switch */
Err_Out:
rc = FALSE;
Done:
if (Infile)
(void) fclose (Infile);
if (fsent < 0)
ZS_EndSend ();
XON_DISABLE ();
XON_ENABLE ();
return rc;
} /* send_Zmodem */
/*--------------------------------------------------------------------------*/
/* ZS SEND BINARY HEADER */
/* Send ZMODEM binary header hdr of type type */
/*--------------------------------------------------------------------------*/
void ZS_SendBinaryHeader (unsigned short type, register byte *hdr)
{
register unsigned short crc;
int n;
#ifdef DEBUG
show_debug_name ("ZS_SendBinaryHeader");
#endif
BUFFER_BYTE (ZPAD);
BUFFER_BYTE (ZDLE);
if ((Crc32t = Txfcs32) != 0)
ZS_32SendBinaryHeader (type, hdr);
else
{
BUFFER_BYTE (ZBIN);
ZS_SendByte ((byte) type);
crc = Z_UpdateCRC (type, 0);
for (n = 4; --n >= 0;)
{
ZS_SendByte (*hdr);
crc = Z_UpdateCRC (((unsigned short) (*hdr++)), crc);
}
ZS_SendByte ((byte) (crc >> 8));
ZS_SendByte ((byte) crc);
UNBUFFER_BYTES ();
}
if (type != ZDATA)
{
while (CARRIER && !OUT_EMPTY ())
time_release ();
if (!CARRIER)
CLEAR_OUTBOUND ();
}
} /* ZS_SendBinaryHeader */
/*--------------------------------------------------------------------------*/
/* ZS SEND BINARY HEADER */
/* Send ZMODEM binary header hdr of type type */
/*--------------------------------------------------------------------------*/
void ZS_32SendBinaryHeader (unsigned short type, register byte *hdr)
{
unsigned long crc;
int n;
#ifdef DEBUG
show_debug_name ("ZS_32SendBinaryHeader");
#endif
BUFFER_BYTE (ZBIN32);
ZS_SendByte ((byte) type);
crc = 0xFFFFFFFF;
crc = Z_32UpdateCRC (type, crc);
for (n = 4; --n >= 0;)
{
ZS_SendByte (*hdr);
crc = Z_32UpdateCRC (((unsigned short) (*hdr++)), crc);
}
crc = ~crc;
for (n = 4; --n >= 0;)
{
ZS_SendByte ((byte) crc);
crc >>= 8;
}
UNBUFFER_BYTES ();
} /* ZS_SendBinaryHeader */
/*--------------------------------------------------------------------------*/
/* ZS SEND DATA */
/* Send binary array buf with ending ZDLE sequence frameend */
/*--------------------------------------------------------------------------*/
void ZS_SendData (register byte *buf, int length, unsigned short frameend)
{
register unsigned short crc;
#ifdef DEBUG
show_debug_name ("ZS_SendData");
#endif
if (Crc32t)
ZS_32SendData (buf, length, frameend);
else
{
crc = 0;
for (; --length >= 0;)
{
ZS_SendByte (*buf);
crc = Z_UpdateCRC (((unsigned short) (*buf++)), crc);
}
BUFFER_BYTE (ZDLE);
BUFFER_BYTE ((unsigned char) frameend);
crc = Z_UpdateCRC (frameend, crc);
ZS_SendByte ((byte) (crc >> 8));
ZS_SendByte ((byte) crc);
UNBUFFER_BYTES ();
}
if (frameend == ZCRCW)
{
SENDBYTE (XON);
while (CARRIER && !OUT_EMPTY ())
time_release ();
if (!CARRIER)
CLEAR_OUTBOUND ();
}
} /* ZS_SendData */
/*--------------------------------------------------------------------------*/
/* ZS SEND DATA with 32 bit CRC */
/* Send binary array buf with ending ZDLE sequence frameend */
/*--------------------------------------------------------------------------*/
void ZS_32SendData (register byte *buf, int length, unsigned short frameend)
{
unsigned long crc;
#ifdef DEBUG
show_debug_name ("ZS_32SendData");
#endif
crc = 0xFFFFFFFF;
for (; --length >= 0; ++buf)
{
ZS_SendByte (*buf);
crc = Z_32UpdateCRC (((unsigned short) (*buf)), crc);
}
BUFFER_BYTE (ZDLE);
BUFFER_BYTE ((unsigned char) frameend);
crc = Z_32UpdateCRC (frameend, crc);
crc = ~crc;
for (length = 4; --length >= 0;)
{
ZS_SendByte ((byte) crc);
crc >>= 8;
}
UNBUFFER_BYTES ();
} /* ZS_SendData */
/*--------------------------------------------------------------------------*/
/* ZS SEND BYTE */
/* Send character c with ZMODEM escape sequence encoding. */
/* Escape XON, XOFF. Escape CR following @ (Telenet net escape) */
/*--------------------------------------------------------------------------*/
void ZS_SendByte (register byte c)
{
static byte lastsent;
switch (c)
{
case 015:
case 0215:
if ((lastsent & 0x7F) != '@')
goto SendIt;
case 020:
case 021:
case 023:
case 0220:
case 0221:
case 0223:
case ZDLE:
/*--------------------------------------------------*/
/* Quoted characters */
/*--------------------------------------------------*/
BUFFER_BYTE (ZDLE);
c ^= 0x40;
default:
/*--------------------------------------------------*/
/* Normal character output */
/*--------------------------------------------------*/
SendIt:
BUFFER_BYTE (lastsent = c);
} /* switch */
} /* ZS_SendByte */
/*--------------------------------------------------------------------------*/
/* ZS GET RECEIVER INFO */
/* Get the receiver's init parameters */
/*--------------------------------------------------------------------------*/
int ZS_GetReceiverInfo ()
{
int n;
#ifdef DEBUG
show_debug_name ("ZS_GetReceiverInfo");
#endif
for (n = 10; --n >= 0;)
{
switch (Z_GetHeader ((byte *)Rxhdr))
{
case ZCHALLENGE:
/*--------------------------------------*/
/* Echo receiver's challenge number */
/*--------------------------------------*/
Z_PutLongIntoHeader (Rxpos);
Z_SendHexHeader (ZACK, (byte *)Txhdr);
continue;
case ZCOMMAND:
/*--------------------------------------*/
/* They didn't see our ZRQINIT */
/*--------------------------------------*/
Z_PutLongIntoHeader (0L);
Z_SendHexHeader (ZRQINIT, (byte *)Txhdr);
continue;
case ZRINIT:
/*--------------------------------------*/
/* */
/*--------------------------------------*/
Rxflags = 0377 & Rxhdr[ZF0];
Rxbuflen = ((word) Rxhdr[ZP1] << 8) | Rxhdr[ZP0];
Txfcs32 = Rxflags & CANFC32;
return OK;
case ZCAN:
case RCDO:
case TIMEOUT:
return ERROR;
case ZRQINIT:
if (Rxhdr[ZF0] == ZCOMMAND)
continue;
default:
Z_SendHexHeader (ZNAK, (byte *)Txhdr);
continue;
} /* switch */
} /* for */
return ERROR;
} /* ZS_GetReceiverInfo */
/*--------------------------------------------------------------------------*/
/* ZS SEND FILE */
/* Send ZFILE frame and begin sending ZDATA frame */
/*--------------------------------------------------------------------------*/
int ZS_SendFile (int blen, int wazoo)
{
register int c;
long t;
#ifdef DEBUG
show_debug_name ("ZS_SendFile");
#endif
for (;;)
{
if (got_ESC ())
{
CLEAR_OUTBOUND ();
XON_DISABLE (); /* Make sure xmitter is
* unstuck */
send_can (); /* transmit at least 10 cans */
t = timerset (200); /* wait no more than 2
* seconds */
while (!timeup (t) && !OUT_EMPTY () && CARRIER)
time_release (); /* Give up slice while
* waiting */
XON_ENABLE (); /* Turn XON/XOFF back on... */
z_log (MSG_TXT(M_KBD_MSG));
return ERROR;
}
else if (!CARRIER)
return ERROR;
Txhdr[ZF0] = LZCONV; /* Default file conversion
* mode */
Txhdr[ZF1] = LZMANAG; /* Default file management
* mode */
Txhdr[ZF2] = LZTRANS; /* Default file transport
* mode */
Txhdr[ZF3] = 0;
ZS_SendBinaryHeader (ZFILE, (byte *)Txhdr);
ZS_SendData (Txbuf, blen, ZCRCW);
Again:
switch (c = Z_GetHeader ((byte *)Rxhdr))
{
case ZRINIT:
while ((c = Z_GetByte (50)) > 0)
if (c == ZPAD)
goto Again;
/* Fall thru to */
default:
continue;
case ZCAN:
case RCDO:
case TIMEOUT:
case ZFIN:
case ZABORT:
return ERROR;
case ZSKIP:
/*-----------------------------------------*/
/* Other system wants to skip this file */
/*-----------------------------------------*/
return c;
case ZRPOS:
/*-----------------------------------------*/
/* Resend from this position... */
/*-----------------------------------------*/
(void) fseek (Infile, Rxpos, SEEK_SET);
if (Rxpos != 0L)
{
status_line (MSG_TXT(M_SYNCHRONIZING_OFFSET), Rxpos);
CLEAR_OUTBOUND (); /* Get rid of queued data */
XON_DISABLE (); /* End XON/XOFF restraint */
SENDBYTE (XON); /* Send XON to remote */
XON_ENABLE (); /* Start XON/XOFF again */
}
LastZRpos = Strtpos = Txpos = Rxpos;
ZRPosCount = 10;
CLEAR_INBOUND ();
return ZS_SendFileData (wazoo);
} /* switch */
} /* while */
} /* ZS_SendFile */
/*--------------------------------------------------------------------------*/
/* ZS SEND FILE DATA */
/* Send the data in the file */
/*--------------------------------------------------------------------------*/
int ZS_SendFileData (int wazoo)
{
register int c, e;
int i;
unsigned int rate;
char j[100];
word newcnt;
word blklen;
word maxblklen;
word goodblks = 0;
word goodneeded = 1;
long t;
#ifdef DEBUG
show_debug_name ("ZS_SendFileData");
#endif
rate = cur_baud.rate_value;
maxblklen = (rate < 300) ? 128 : rate / 300 * 256;
if (maxblklen > WAZOOMAX)
maxblklen = WAZOOMAX;
if (!wazoo && maxblklen > KSIZE)
maxblklen = KSIZE;
if (Rxbuflen && maxblklen > (unsigned)Rxbuflen)
maxblklen = Rxbuflen;
if (wazoo && (remote_capabilities & ZED_ZIPPER))
maxblklen = KSIZE;
blklen = (fstblklen != 0) ? fstblklen : maxblklen;
goodneeded = (fstblklen != 0) ? 8 : 1;
SomeMore:
if (CHAR_AVAIL ())
{
WaitAck:
switch (c = ZS_SyncWithReceiver (1))
{
case ZSKIP:
/*-----------------------------------------*/
/* Skip this file */
/*-----------------------------------------*/
return c;
case ZACK:
break;
case ZRPOS:
/*-----------------------------------------*/
/* Resume at this position */
/*-----------------------------------------*/
blklen = ((blklen >> 2) > 64) ? blklen >> 2 : 64;
goodblks = 0;
goodneeded = ((goodneeded << 1) > 16) ? 16 : goodneeded << 1;
break;
case ZRINIT:
/*-----------------------------------------*/
/* Receive init */
/*-----------------------------------------*/
if (locate_y && !(fullscreen && un_attended))
gotoxy (2, (byte) locate_y - 1);
throughput (1, Txpos - Strtpos);
return OK;
case TIMEOUT:
/*-----------------------------------------*/
/* Timed out on message from other side */
/*-----------------------------------------*/
break;
default:
z_log (MSG_TXT(M_CAN_MSG));
(void) fclose (Infile);
return ERROR;
} /* switch */
/*
* Noise probably got us here. Odds of surviving are not good. But we
* have to get unstuck in any event.
*
*/
Z_UncorkTransmitter (); /* Get our side free if need
* be */
SENDBYTE (XON); /* Send an XON to release
* other side */
while (CHAR_AVAIL ())
{
switch (MODEM_IN ())
{
case CAN:
case RCDO:
case ZPAD:
goto WaitAck;
} /* switch */
} /* while */
} /* while */
newcnt = Rxbuflen;
Z_PutLongIntoHeader (Txpos);
ZS_SendBinaryHeader (ZDATA, (byte *)Txhdr);
do
{
if (got_ESC ())
{
CLEAR_OUTBOUND ();
XON_DISABLE (); /* Make sure xmitter is
* unstuck */
send_can (); /* transmit at least 10 cans */
t = timerset (200); /* wait no more than 2
* seconds */
while (!timeup (t) && !OUT_EMPTY () && CARRIER)
time_release (); /* Give up slice while
* waiting */
XON_ENABLE (); /* Turn XON/XOFF back on... */
z_log (MSG_TXT(M_KBD_MSG));
goto oops;
}
if (!CARRIER)
goto oops;
if ((unsigned)(c = fread (Txbuf, 1, blklen, Infile)) != z_size)
{
if (fullscreen && un_attended)
{
sb_move (file_hWnd, 2, 12);
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_SIZE ),
ultoa (((unsigned long) (z_size = c)), e_input, 10));
#ifndef MILQ
sb_puts (file_hWnd, " ");
#endif
elapse_time ();
sb_show ();
}
else
{
gotoxy (locate_x + 10, locate_y);
(void) cputs (ultoa (((unsigned long) (z_size = c)), e_input, 10));
(void) putch (' ');
}
}
if ((unsigned)c < blklen)
e = ZCRCE;
else if (Rxbuflen && (newcnt -= c) <= 0)
e = ZCRCW;
else e = ZCRCG;
ZS_SendData (Txbuf, c, e);
i = (int) ((file_length - Txpos) * 10 / rate + 53) / 54;
(void) sprintf (j, "%3d min", i);
if (fullscreen && un_attended)
{
sb_move (file_hWnd, 2, 2);
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_TOTAL ),
ultoa (((unsigned long) Txpos), e_input, 10));
#ifndef MILQ
sb_puts (file_hWnd, " ");
#endif
sb_move (file_hWnd, 2, 69);
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_DTTM ), j );
elapse_time ();
sb_show ();
}
else
{
gotoxy (locate_x, locate_y);
(void) cputs (ultoa (((unsigned long) Txpos), e_input, 10));
(void) putch (' ');
(void) putch (' ');
gotoxy (locate_x + 20, locate_y);
(void) printf ("%s", j);
(void) putch (' ');
}
Txpos += c;
if (blklen < maxblklen && ++goodblks > goodneeded)
{
blklen = ((blklen << 1) < maxblklen) ? blklen << 1 : maxblklen;
goodblks = 0;
}
if (e == ZCRCW)
goto WaitAck;
while (CHAR_AVAIL ())
{
switch (MODEM_IN ())
{
case CAN:
case RCDO:
case ZPAD:
/*--------------------------------------*/
/* Interruption detected; */
/* stop sending and process complaint */
/*--------------------------------------*/
z_message (MSG_TXT(M_TROUBLE));
CLEAR_OUTBOUND ();
ZS_SendData (Txbuf, 0, ZCRCE);
goto WaitAck;
} /* switch */
} /* while */
} /* do */
while (e == ZCRCG);
for (;;)
{
Z_PutLongIntoHeader (Txpos);
ZS_SendBinaryHeader (ZEOF, (byte *)Txhdr);
switch (ZS_SyncWithReceiver (7))
{
case ZACK:
continue;
case ZRPOS:
/*-----------------------------------------*/
/* Resume at this position... */
/*-----------------------------------------*/
goto SomeMore;
case ZRINIT:
/*-----------------------------------------*/
/* Receive init */
/*-----------------------------------------*/
if (locate_y && !(fullscreen && un_attended))
gotoxy (2, (byte) locate_y - 1);
throughput (1, Txpos - Strtpos);
return OK;
case ZSKIP:
/*-----------------------------------------*/
/* Request to skip the current file */
/*-----------------------------------------*/
z_log (MSG_TXT(M_SKIP_MSG));
CLEAR_IOERR ();
(void) fclose (Infile);
return c;
default:
oops:
z_log (MSG_TXT(M_CAN_MSG));
(void) fclose (Infile);
return ERROR;
} /* switch */
} /* while */
} /* ZS_SendFileData */
/*--------------------------------------------------------------------------*/
/* ZS SYNC WITH RECEIVER */
/* Respond to receiver's complaint, get back in sync with receiver */
/*--------------------------------------------------------------------------*/
int ZS_SyncWithReceiver (int num_errs)
{
register int c;
char j[50];
#ifdef DEBUG
show_debug_name ("ZS_SyncWithReceiver");
#endif
for (;;)
{
c = Z_GetHeader ((byte *)Rxhdr);
CLEAR_INBOUND ();
switch (c)
{
case TIMEOUT:
z_message (MSG_TXT(M_TIMEOUT));
if ((num_errs--) >= 0)
break;
case ZCAN:
case ZABORT:
case ZFIN:
case RCDO:
z_log (MSG_TXT(M_ERROR));
return ERROR;
case ZRPOS:
if (Rxpos == LastZRpos) /* Same as last time? */
{
if (!(--ZRPosCount)) /* Yup, 10 times yet? */
return ERROR; /* Too many, get out */
}
else ZRPosCount = 10; /* Reset repeat count */
LastZRpos = Rxpos; /* Keep track of this */
rewind (Infile); /* In case file EOF seen */
(void) fseek (Infile, Rxpos, SEEK_SET);
Txpos = Rxpos;
(void) sprintf (j, MSG_TXT(M_RESENDING_FROM),
ultoa (((unsigned long) (Txpos)), e_input, 10));
z_message (j);
return c;
case ZSKIP:
z_log (MSG_TXT(M_SKIP_MSG));
case ZRINIT:
CLEAR_IOERR ();
(void) fclose (Infile);
return c;
case ZACK:
z_message (NULL);
return c;
default:
z_message (IDUNNO_msg);
ZS_SendBinaryHeader (ZNAK, (byte *)Txhdr);
continue;
} /* switch */
} /* while */
} /* ZS_SyncWithReceiver */
/*--------------------------------------------------------------------------*/
/* ZS END SEND */
/* Say BIBI to the receiver, try to do it cleanly */
/*--------------------------------------------------------------------------*/
void ZS_EndSend ()
{
#ifdef DEBUG
show_debug_name ("ZS_EndSend");
#endif
for (;;)
{
Z_PutLongIntoHeader (0L);
ZS_SendBinaryHeader (ZFIN, (byte *)Txhdr);
switch (Z_GetHeader ((byte *)Rxhdr))
{
case ZFIN:
SENDBYTE ('O');
SENDBYTE ('O');
while (CARRIER && !OUT_EMPTY ())
time_release ();
if (!CARRIER)
CLEAR_OUTBOUND ();
/* fallthrough... */
case ZCAN:
case RCDO:
case TIMEOUT:
return;
} /* switch */
} /* while */
} /* ZS_EndSend */